# -*- coding: utf-8 -*-

"""
  Dynami DNS service for VALUE-DOMAIN.COM.
  URL: http://www.value-domain.com/

  author sato.tatsuma
"""

import time
from httplib import HTTPConnection, CannotSendRequest, OK
from exception import InvalidRequest, InvalidDomainPassword, InvalidHost, InvalidIPAddress
from exception import PasswordError, ServerBusy, UnknownError

class DdnsValueDomain(object):
  """
    Dynami DNS service manager class for VALUE-DOMAIN.COM.
    Send HTTP request for Value-Domain CGI.
  """
  def __init__(self, domain, password, request_domain, request_url, domain_host=None, ipaddress=None):
    self.domain = domain
    self.password = password
    self.request_domain = request_domain
    self.request_url = request_url
    self.domain_host = domain_host
    self.ipaddress = ipaddress

  def update_ipaddress(self):
    """
      Check ip address and set IPAddress.
      Request to Value-Domain's CGI to know IP address.
    """
    conn = HTTPConnection(self.request_domain)
    try:
      conn.request('GET', self.request_url + '?ip')
    except CannotSendRequest:
      None
    else:
      response = conn.getresponse()
      if OK == response.status:
        # Success to request and get response.
        self.ipaddress = response.read()
        message = "domain %s, host %s IP address changed to %s."
        # Print log.
        print message % (self.domain, self.domain_host, self.ipaddress)

  def update_dns(self):
    """
      Update DNS record.

      If self.ipaddress is None, not set i parameter in request param.
      When Value-Domain use the ipaddress that get from HTTP connection request.

    """
    request_param = "?d=%s&p=%s" % (self.domain, self.password)
    if self.domain_host:
      request_param += "&h=%s" % self.domain_host
    else:
      # Default host value is '*'
      request_param += "&h=*"
    if self.ipaddress:
      request_param += "&i=%s" % self.ipaddress

    conn = HTTPConnection(self.request_domain)
    try:
      conn.request('GET', self.request_url + request_param)
      # Print request URL log.
      print "REQUEST," + time.ctime() + ",http://" + self.request_domain + self.request_url + request_param
    except CannotSendRequest, e:
      raise e
    else:
      response = conn.getresponse()
      if OK == response.status:
        # Value-Domain return text based result.
        # example:
        # status=4
        # Invalid Password.
        body = response.read()
        statusline = body.splitlines()[0]
        status = int(statusline.split('=')[1])
        conn.close()

        if 0 == status:
          # Success to update DNS record.
          print "UPDATE,%s,%s,%s,%s" % (time.ctime(), self.domain, self.domain_host, self.ipaddress)
          return True
        elif 1 == status:
          # Invalid request. Need debug.
          raise InvalidRequest
        elif 2 == status:
          # Invalid domain or password.
          raise InvalidDomainPassword
        elif 3 == status:
          # Invalid IP address.
          raise InvalidIPAddress
        elif 4 == status:
          # Password is not mutched.
          raise PasswordError
        elif 5 == status:
          # Value-Domain's database server is busy.
          raise ServerBusy
        else:
          # Unknown error.
          raise UnknownError
      else:
        conn.close()
